use std::sync::{Arc, Barrier, Condvar, Mutex};
use std::thread;
use std::time::{Duration, SystemTime};

#[cfg(test)]
mod tests {
    #[test]
    fn test_unsafe_seq() {
        super::start();
    }
}

/// Rust 除支持互斥锁和读写锁之外 ，还支持 屏障( Barrier)和条件变量( Condition Variable)同步原语。
pub fn start() {
    // 屏障
    let mut handlers = Vec::with_capacity(5);
    let barrier = Arc::new(Barrier::new(5));
    for _ in 0..5 {
        let c = barrier.clone();
        handlers.push(thread::spawn(move || {
            println!("before wait");
            c.wait();
            println!("after wait");
        }));
    }
    for handler in handlers {
        handler.join();
    }

    // 信号量(条件变量跟屏障有点相似，但它不是阻塞全部线程，而是在满足指定条件之前阻塞某一个得到互斥锁的线程 。)
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair_clone = pair.clone();
    thread::spawn(move || {
        let &(ref lock, ref cvar) = &*pair_clone;
        let mut started = lock.lock().unwrap();
        println!("child 获取锁 {:?}", SystemTime::now());
        *started = true;
        cvar.notify_one();
    });

    let &(ref lock, ref cvar) = &*pair;
    let mut started = lock.lock().unwrap();
    println!("main 获取锁 {:?}", SystemTime::now());
    while !*started {
        println!("{}", started); // false
        started = cvar.wait(started).unwrap();
        println!("{}", started); // true
    }
}
